/**
 * @author: Jone
 * @version: 2.6
 * 开发文档（wiki）：http://wiki.cy.com/display/wzhdkf/ja+v2.6
 * 开发文档（有道）：http://note.youdao.com/noteshare?id=76733b560106ac5248b608bb53a9c9bc&sub=81F4782917A945F3A7A5FE69992F8ABC
 * 初始化流程图：https://www.processon.com/view/link/5eccf479e0b34d5f2630595e
 **/
'use strict';

(function (window) {
    var that,

        name = 'ja',

        version = '2.6',

        arrHost = [
            'kzgj.cy.com'
        ],      // 请求通用域名(http://join-activity.changyou.com) 接口

        debugDomain = [
            'local-activity.changyou.com',
            'local-join-activity.changyou.com',
            'dev-activity.changyou.com'
        ],      // isDebug 生效域名

        vconsoleDomain = [
            'local-activity.changyou.com',
            'local-join-activity.changyou.com',
            'dev-activity.changyou.com',
            'test-activity.changyou.com'
        ],      // isVConsole 生效域名

        origin = location.origin || location.protocol + '//' + location.host,

        staticObj = {
            'local-activity.changyou.com': 'http://local-static2.changyou.com',
            'local-join-activity.changyou.com': 'http://local-static2.changyou.com',
            'dev-activity.changyou.com': 'http://dev-static2.changyou.com',
            'test-activity.changyou.com': 'http://test-static2.changyou.com'
        },

        staticOrigin = staticObj[location.host] || 'http://static2.changyou.com',

        urlWxBind = '//tlus.changyou.com/xtl/wxBind/20180910/mobile/index.html',    // 微信账号绑定链接

        imgHost = '//i0.cy.com',

        isIos = /iphone|ipod|ipad/i.test(window.navigator.userAgent.toLowerCase()),

        isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),

        isWechat = window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger';

    /**
     * == 全局对象 ==
     * 注：code 为初始化状态：0 初始化未完成;1 初始化完成/已登录;2 初始化完成/未登录;1106 活动未开始;1103 活动已结束;1102 活动无效
     *   glob 为全局状态管理，包含所有内部状态
     *   _glob 只包含初始化回调对象
     **/
    var glob = {};
    var _glob = {
        code: 0,            // 活动信息 landing/init 返回code
        isIos: isIos,
        isMobile: isMobile,
        isWechat: isWechat,
        urlWxBind: urlWxBind,
        staticOrigin: staticOrigin,
        isLogin: undefined,         // 是否登录
        userInfo: undefined,        // 账号信息
        wechatInfo: undefined,      // 微信账号信息
        wxBindName: undefined      // 微信绑定账号昵称
    };

    // 构造函数合并
    function Mixin(recClass, giveClass) {
        if (arguments.length > 2) {
            for (var i = 2; i < arguments.length; ++i) {
                var name = arguments[i];
                recClass.prototype[name] = giveClass.prototype[name];
            }
        } else {
            for (var key in giveClass.prototype) {
                if (!recClass.prototype[key]) {
                    recClass.prototype[key] = giveClass.prototype[key];
                }
            }
        }
    }
    // 新旧版本方法合并
    function MixinDeep(recClass, giveClass) {
        for (var key in giveClass.prototype) {
            if (recClass.prototype[key]) {
                $.extend(recClass.prototype[key], giveClass.prototype[key])
            }else {
                recClass.prototype[key] = giveClass.prototype[key];
            }
        }
    }
    // 旧版本直接挂载ja方法
    function MixinSimple(recClass, giveClass, module) {
        if (arguments.length > 3) {
            for (var i = 3; i < arguments.length; ++i) {
                var name = arguments[i];
                recClass.prototype[name] = giveClass.prototype[module][name];
            }
        }
    }

    // xhr 兼容写法
    function createXhr(){
        if(typeof XMLHttpRequest !== "undefined"){
            return new XMLHttpRequest();
        }else if(typeof ActiveXObject !== "undefined"){
            var verStr = [
                "MSXML.XMLHttp.6.0",
                "MSXML.XMLHttp.3.0",
                "MSXML.XMLHttp"];
            for(var n in verStr){
                try{
                    var xhr = new ActiveXObject(verStr[n]);
                    return xhr;
                }catch(e){
                    console.log(e);
                }
            }
        }else{
            console.log("sorry,您的计算机不支持ajax通信！");
        }
    }

    // jquery ajax 默认选项设置
    function setupAjax() {
        $.ajaxSetup({
            dataType: 'json',
            cache: false,
            xhrFields: {withCredentials: true},
            headers: {
                'Authorization': glob.token,
                'APP': glob.app,
                'ACTIVITY': glob.activity,
                'VERSIONCODE': glob.version,
                'PLAT': glob.platform,
                'CYSCID': glob.cyscid,
                'CYSTID': glob.cystid
            },
            complete: function(request, status) {
                if(status === 'success' && request.responseJSON) {
                    switch (Number(request.responseJSON.code)) {
                        case 1012:case 1019:
                            if(glob.loginMethod) {
                                storage.setMethod('loginMethod');
                                utils.reload();
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
        })
    }

    // jquery ajax 请求拦截
    $.ajaxPrefilter(function (options, originalOptions, jqXHR) {
        if (glob.isDebug) {
            options.type = 'GET';
            if (options.url.indexOf('changyou.com') !== -1) {
                options.url = options.url + '.json';
            }else {
                options.url = glob.originOnly + options.url + '.json';
            }
        }
    });



    // bind IE8 兼容
    if(!Function.prototype.bind){
        Function.prototype.bind = function(oThis){
            if(typeof this !== 'function') {
                throw new TypeError('试图被绑定的东西是不可调用的')
            }
            var aArgs = Array.prototype.slice.call(arguments,1),
                fToBind = this,
                fNOP = function(){};
            var fBound = function(){
                return fToBind.apply(this instanceof fNOP ? this : oThis,
                    aArgs.concat(Array.prototype.slice.call(arguments)))
            };
            fNOP.prototype = this.prototype;
            fBound.prototype = new fNOP();
            return fBound;
        }
    }

    /**
     * == 中间件，用来管理初始化流程 ==
     **/
    var MidWare = function () {
        this.cache = [];
        this.options = {};
    };
    MidWare.prototype = {
        use: function (fn) {
            this.cache.push(fn);
            return this;
        },
        next: function (argument) {
            if (this.cache && this.cache.length > 0) {
                var ware = this.cache.shift();
                ware.call(this, this.options || {}, this.next.bind(this));
            }
        },
        handleRequest: function (options) {
            this.options = options;
            this.next();
        }
    };

    /**
     * == 工具类 ==
     **/
    function Utils() {

    }
    Utils.prototype = {
        /*
        * 获取地址中‘？’后面的值
        *   name 必填，要获取值的属性
        *   url 非必填，指定获取的路径
        * */
        getQueryString: function (name, url) {
            var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)'),
                search = unescape((url && url.split('?')[1]) || window.location.search.substr(1)),
                r = search.match(reg);
            if (r != null) return r[2];
            return null;
        },
        /*
        * 获取地址中传递值的对象
        *   url 非必填，指定获取的路径
        * */
        getParams: function (url) {
            var url = url || location.href; //获取url中"?"符后的字串
            var theRequest = new Object();
            if (url.indexOf("?") != -1) {
                var str = url.split('?')[1];
                var strs = str.split("&");
                for (var i = 0; i < strs.length; i++) {
                    theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
                }
            }
            return theRequest;
        },
        // 判断某字符串是否是JSON格式
        isJSON: function (str) {
            if (typeof str == 'string') {
                try {
                    return typeof JSON.parse(str) == 'object';
                } catch (e) {
                    return false;
                }
            }
        },
        // 删除对象中值为undefined的键值对
        objDelUndefined: function (obj) {
            var json = {};
            for (var key in obj) {
                if (obj[key]) json[key] = obj[key];
            }
            return json;
        },
        // 回到顶部
        backTop: function (num, time) {
            $('html, body').animate({scrollTop: (num || 0) + 'px'}, time || 300);
        },
        // 单数变双数
        getTwo: function (n) {
            n = n.toString();
            return n[1] ? n : "0" + n;
        },
        // 对当前地址拼接参数
        setUrlParams: function (val) {
            var str = '?infoData=',
                arr = [];
            for (var key in val) {
                var value = val[key] || typeof val[key] === 'number' ? val[key] : '';
                arr.push(key + '@@@' + encodeURIComponent(value));
            }
            return str + arr.join('@@@@');
        },
        // 获取当前路径或指定路径地址参数，与setUrlParams配合使用
        getUrlParams: function (url) {
            var json = {},
                info = this.getQueryString('infoData', url);
            if (info) {
                info.split('@@@@').forEach(function (item) {
                    var key = item.split('@@@')[0],
                        val = item.split('@@@')[1];
                    json[key] = decodeURIComponent(val);
                });
            }
            return json;
        },
        // 格式化 日期
        formatDate: function (now) {
            now = now ? new Date(now) : new Date();
            var year = now.getFullYear();
            var month = now.getMonth() + 1;
            var date = now.getDate();
            var hour = now.getHours();
            var minute = now.getMinutes();
            var second = now.getSeconds();
            return year + "-" + this.getTwo(month) + "-" + this.getTwo(date);
        },
        // 格式化 日期+时间
        formatDateTime: function (now) {
            now = now ? new Date(now) : new Date();
            var year = now.getFullYear();
            var month = now.getMonth() + 1;
            var date = now.getDate();
            var hour = now.getHours();
            var minute = now.getMinutes();
            var second = now.getSeconds();
            return year + "-" + this.getTwo(month) + "-" + this.getTwo(date) + " " + this.getTwo(hour) + ":" + this.getTwo(minute) + ":" + this.getTwo(second);
        },
        urlAddKey: function (url, key, val) {
            key = (key || 't') + '=';  //默认是"t"
            url = url || location.href;
            var reg = new RegExp(key + '\\d+');  //正则：t=1472286066028
            var timestamp = val || +new Date();
            if (url.indexOf(key) > -1) { //有时间戳，直接更新
                return url.replace(reg, key + timestamp);
            } else {  //没有时间戳，加上时间戳
                if (url.indexOf('\?') > -1) {
                    var urlArr = url.split('\?');
                    if (urlArr[1]) {
                        return urlArr[0] + '?' + key + timestamp + '&' + urlArr[1];
                    } else {
                        return urlArr[0] + '?' + key + timestamp;
                    }
                } else {
                    if (url.indexOf('#') > -1) {
                        return url.split('#')[0] + '?' + key + timestamp + location.hash;
                    } else {
                        return url + '?' + key + timestamp;
                    }
                }
            }
        },
        href: function (url) {
            if(isIos) {
                location.href = url;
            }else {
                location.replace(url);
            }
        },
        reload: function () {
            var paramsObj = this.getParams(),
                paramsStr = '';
            delete paramsObj.jcode;
            if(Object.keys(paramsObj).length > 0) paramsStr = '?' + $.param(paramsObj);
            location.href = origin + location.pathname + paramsStr;
        },
        // 对象深层合并
        deepMerge: function (obj1, obj2) {
            for (var key in obj2) {
                obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ?
                    utils.deepMerge(obj1[key], obj2[key]) : obj1[key] = obj2[key];
            }
            return obj1;
        },
        // 判断IE浏览器的具体版本
        IEVersion: function() {
            var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
            var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
            var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
            var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
            if(isIE) {
                var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
                reIE.test(userAgent);
                var fIEVersion = parseFloat(RegExp["$1"]);
                if(fIEVersion == 7) {
                    return 7;
                } else if(fIEVersion == 8) {
                    return 8;
                } else if(fIEVersion == 9) {
                    return 9;
                } else if(fIEVersion == 10) {
                    return 10;
                } else {
                    return 6;//IE版本<=7
                }
            } else if(isEdge) {
                return 'edge';//edge
            } else if(isIE11) {
                return 11; //IE11
            }else{
                return -1;//不是ie浏览器
            }
        },
        getFunName: function(fun) {
            var matches = fun.toString().match(/function\s*(\w*)/i);
            return matches[1];
        },
        vconsole: function() {
            $.getScript(staticOrigin + '/act/all/cdn/join-activity/2.6/lib/vconsole.min.js', function() {
                var vConsole = new VConsole();
            })
        },
        excelToJson: function(url, callback) {
            var json = {};
            $.getScript(staticOrigin + '/act/all/cdn/xlsx/0.16.6/xlsx.core.min.js', function() {
                var xhr = createXhr();
                xhr.open('get', url, true);
                xhr.responseType = 'arraybuffer';
                xhr.onload = function (e) {
                    if (xhr.status == 200) {
                        var data = new Uint8Array(xhr.response);
                        var wb = XLSX.read(data, { type: 'array' });
                        var sheetNameList = wb.SheetNames;
                        if(sheetNameList.length > 1) {
                            json = {};
                            for(var i = 0; i < sheetNameList.length; i++) {
                                json[sheetNameList[i]] = XLSX.utils.sheet_to_json(wb.Sheets[sheetNameList[i]])
                            }
                        }else {
                            json = XLSX.utils.sheet_to_json(wb.Sheets[sheetNameList[0]]);
                        }
                        callback && callback(json);
                    }
                };
                xhr.send();
            });
        },
        phoneVersion: function() {
            if(isMobile) {
                var modelV = '';
                $.ajax({
                    url: '/act/all/cdn/mobile-detect/1.4.4/mobile-detect.js',
                    async: false,
                    dataType: "script",
                    success: function() {
                        Array.prototype.contains = function(needle) {
                            for (i in this) {
                                if (this[i].indexOf(needle) > 0)
                                    return i;
                            }
                            return -1;
                        };
                        var device_type = navigator.userAgent;
                        var md = new MobileDetect(device_type);
                        var os = md.os(); // 获取系统
                        var model = "";
                        if (os == "iOS") { //ios系统的处理
                            os = md.os() + md.version("iPhone");
                            model = md.mobile();
                            // model = iphone();
                        } else if (os == "AndroidOS") { //Android系统的处理
                            os = md.os() + md.version("Android");
                            var sss = device_type.split(";");
                            var i = sss.contains("Build/");
                            if (i > -1) {
                                model = sss[i].substring(0, sss[i].indexOf("Build/"));
                            }
                        }
                        modelV = model + '-' + os;
                    }
                });
                return modelV;
            }else {
                return undefined;
            }
        },
        /**
         * @desc 函数节流
         * @param func 函数
         * @param wait 延迟执行毫秒数
         * @param type 1 表时间戳版(立即执行)，2 表定时器版(非立即执行)
         */
        throttle: function(func, wait ,type) {
            if(type===2){
                var timeout;
            }else {
                var previous = 0;
            }
            return function() {
                var context = this;
                var args = arguments;
                if(type===2){
                    if (!timeout) {
                        timeout = setTimeout(function() {
                            timeout = null;
                            func.apply(context, args)
                        }, wait)
                    }
                }else {
                    var now = Date.now();
                    if (now - previous > wait) {
                        func.apply(context, args);
                        previous = now;
                    }
                }
            }
        },
        /**
         * @desc 函数防抖
         * @param func 函数
         * @param wait 延迟执行毫秒数
         * @param immediate true 表立即执行，false 表非立即执行
         */
        debounce: function(func,wait,immediate) {
            var timeout;
            return function () {
                var context = this;
                var args = arguments;
                if (timeout) clearTimeout(timeout);
                if (immediate) {
                    var callNow = !timeout;
                    timeout = setTimeout(function() {
                        timeout = null;
                    }, wait)
                    if (callNow) func.apply(context, args)
                }
                else {
                    timeout = setTimeout(function(){
                        func.apply(context, args)
                    }, wait);
                }
            }
        },
        // 弹窗
        win: {
            scrolling: 'no',
            //是否显示滚动条 no,yes,auto
            int: function () {
                var $winClose = $("#winClose");
                $winClose.on('mouseenter',
                    function () {
                        $(this).css("background-image", "url()");
                    });
                $winClose.on('mouseleave',
                    function () {
                        $(this).css("background-image", "url()");
                    });
                $winClose.on('click',
                    function () {
                        $("#mask,#maskTop").fadeOut(function () {
                            $(this).remove();
                        });
                    });
            },
            open: function (width, height, src) {
                var iframeHeight = height;
                var marginLeft = width / 2;
                var marginTop = height / 2;
                var inntHtml = '';
                inntHtml += '<div id="mask" style="width:100%; height:100%; position:fixed; top:0; left:0; z-index:1999;background:#cccccc; filter:alpha(opacity=50); -moz-opacity:0.5; -khtml-opacity: 0.5; opacity:0.5;"></div>';
                inntHtml += '<div id="maskTop" style="width: ' + width + 'px; height: ' + height + 'px;  color: #333; position: fixed; top: 50%; left: 50%; margin-left: -' + marginLeft + 'px; margin-top: -' + marginTop + 'px; z-index: 2999; ">';
                inntHtml += '<div id="maskTitle" style="height: 0;position: relative;">';
                inntHtml += '<div id="winClose" style="width: 28px; height: 28px; cursor: pointer; position: absolute; top: -12px; right: -9px; background-image: url();"></div>';
                inntHtml += '</div>';
                inntHtml += '<iframe width="' + width + '" height="' + iframeHeight + '" frameborder="0" scrolling="' + this.scrolling + '" src="' + src + '"></iframe>';
                inntHtml += '</div>';
                $("body").append(inntHtml);
                this.int();
            },
            close: function () {
                $("#winClose").click();
            }
        },
        // 存储cookie
        cookie: {
            get: function (cname) {
                var name = cname + '=';
                var ca = document.cookie.split(';');
                for (var i = 0; i < ca.length; i++) {
                    var c = ca[i];
                    while (c.charAt(0) == ' ') c = c.substring(1);
                    if (c.indexOf(name) != -1) return c.substring(name.length, c.length);
                }
                return '';
            },
            set: function (cname, cvalue, exdays, domain) {
                var d = new Date();
                d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
                var expires = 'expires=' + d.toUTCString();
                document.cookie = cname + '=' + cvalue + '; ' + expires + '; domain=' + domain + '; path=/';
            },
            del: function (name, domain) {
                this.set(name, '', -1, domain);
            }
        },
        // 存储sessionStorage，自动转换对象存储和获取
        session: {
            set: function (name, value) {
                if (Object.prototype.toString.call(value) === '[object Object]') value = JSON.stringify(value);
                sessionStorage.setItem(name, value)
            },
            get: function (name) {
                var value = sessionStorage.getItem(name);
                return utils.isJSON(value) ? JSON.parse(value) : value;
            }
        }
    };
    var utils = new Utils();

    /**
     * == 弹窗 ==
     **/
    function Dialog() {
    }
    Dialog.prototype = {
        isExist: function (elem) {
            if (typeof elem !== 'undefined' && typeof elem !== null) {
                return true;
            } else {
                return false;
            }
        },
        removeOverlay: function () {
            if (this.isExist($('#Overlay'))) $('#Overlay').remove();
            if (this.isExist($('#Overlay1'))) $('#Overlay1').remove();
        },
        addOverlay: function (cl, op) {
            this.removeOverlay();
            var overlayCss = {
                    position: 'fixed',
                    zIndex: '100',
                    top: '0px',
                    left: '0px',
                    height: '100%',
                    width: '100%',
                    backgroundColor: '#000',
                    filter: 'alpha(opacity=60)',
                    opacity: 0.6
                },
                overlayCss2 = { //for ie 6
                    position: 'absolute',
                    height: $(document).height()
                };
            var overlay = $('<div id="Overlay" class="OverlayBG" />');
            var overlay1 = $('<iframe id="Overlay1" class="OverlayBG"  frameborder="0"  scrolling="no"></iframe>');

            if (this.isExist(cl)) overlayCss.backgroundColor = cl;
            $('body').append(overlay.css(overlayCss));
            if (this.isExist(op)) {
                $('#Overlay').animate({opacity: op}, 0);
            }
        },
        toggleBody: function (isPin) {
            // if (isPin) {
            //     document.body.style.height = '100vh';
            //     document.body.style['overflow-y'] = 'hidden'
            // } else {
            //     document.body.style.height = 'unset';
            //     document.body.style['overflow-y'] = 'auto'
            // }
        },
        popup: function (target) {
            var _this = this;
            this.toggleBody(1);
            this.addOverlay('#000', 0.8);
            if(typeof target === 'string') {
                target = $(target);
            }
            target.css("position", "fixed")
                .css("top", ($(window).height() - target.height()) / 2)
                .css("left", ($(window).width() - target.width()) / 2)
                .css("z-index", "9999")
                .fadeIn();
            $(".pop_close, .dialog_close", target).click(function () {
                _this.hideMask(target);
                return false;
            });
        },
        hideMask: function (target) {
            this.toggleBody(0);
            this.removeOverlay();
            if (target) {
                target.fadeOut();
            } else {
                $('.ja_login_box').fadeOut();
            }
            return false;
        }
    };
    var dialog = new Dialog();

    /**
     * == 提示 ==
     **/
    function Message() {

    }
    Message.prototype = {
        self: function (opt) {
            var _opt = {
                name: '',
                nStyle: {color: '#fff', background: '#606060'},
                value: 'value',
                vStyle: {color: '#fff', background: '#42C02E'}
            };
            utils.deepMerge(_opt, opt);
            if(utils.IEVersion() === -1) {
                console.log('%c ' + _opt.name + ' %c ' + _opt.value,
                    'color:' + _opt.nStyle.color + ';background:' + _opt.nStyle.background + ';border-radius: 3px 0 0 3px',
                    'color:' + _opt.vStyle.color + ';background:' + _opt.vStyle.background + ';padding-right: 5px;border-radius: 0 3px 3px 0')
            }else {
                console.log(_opt.name + ':', _opt.value)
            }
        },
        console: function (name, msg) {
            var _opt = {
                name: name,
                value: msg
            };
            this.self(_opt);
        },
        warning: function (msg) {
            var _opt = {
                name: 'warning',
                nStyle: {color: '#fff'},
                value: msg,
                vStyle: {background: '#ffae47'}
            };
            this.self(_opt);
        },
        error: function (msg) {
            var _opt = {
                name: 'error',
                nStyle: {color: '#fff'},
                value: msg,
                vStyle: {background: '#f00'}
            };
            this.self(_opt)
        },
    };
    var message = new Message();

    /**
     * == 本地存储值统一管理 ==
     **/
    function Storage() {
    }
    Storage.prototype = {
        // 待执行方法名称，存储到本地
        setMethod: function (val) {
            sessionStorage.setItem(glob.appName + ':method', val)
        },
        getMethod: function () {
            return sessionStorage.getItem(glob.appName + ':method')
        },
        removeMethod: function () {
            sessionStorage.removeItem(glob.appName + ':method')
        },
        // 地址栏参数存储（微信授权前，避免丢参）
        setParams: function (val) {
            utils.session.set(glob.appName + ':params', val)
        },
        getParams: function () {
            return utils.session.get(glob.appName + ':params')
        },
        removeParams: function () {
            sessionStorage.removeItem(glob.appName + ':params')
        },
        // 时间戳
        setIsWxLogin: function (val) {
            utils.session.set(glob.appName + ':timestamp', val || Date.now())
        },
        getIsWxLogin: function () {
            return utils.session.get(glob.appName + ':timestamp')
        },
        removeIsWxLogin: function () {
            sessionStorage.removeItem(glob.appName + ':timestamp')
        }
    };
    var storage = new Storage();

    /**
     * == 表单验证 ==
     **/
    function Verify() {}
    Verify.prototype = {
        reg: {
            phone: /^1[3456789]\d{9}$/,
            email: /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/,           // 邮箱
            userName: /^[a-z0-9_-]{3,16}$/,                     // 用户名
            chineseName: /^[\u4E00-\u9FA5]{2,4}$/,              // 中文姓名
        },
        // 手机号
        phone: function (val) {
            if (!val) {
                return '请填写手机号！';
            } else if (!val.match(this.reg.phone)) {
                return '请输入正确的手机号！';
            } else {
                return false;
            }
        },
        // 验证码
        phoneCode: function (val) {
            if (!val) {
                return '请填写验证码！';
            } else if (val.length !== 6) {
                return '验证码错误！'
            } else {
                return false;
            }
        }
    };
    var verify = new Verify();

    /**
     * == 用户通用模块 ==
     **/
    function User() {
    }
    User.prototype = {
        // 获取token
        getToken: function () {
            var info = undefined;
            $.ajax({
                url: glob.originAll + '/landing/init',
                async: false,
                success: function (res) {
                    info = res;
                    if (res.code === 10000) {
                        var item = res.data;
                        if (!item.token) {
                            message.error('无token，请联系后台开发添加');
                        }
                        if (!item.activity) {
                            message.error('无活动信息，请联系后台开发添加');
                        }
                    }else {
                        if(glob.v === '2.1') {
                            var obj = {
                                1106: 2,
                                1103: 3,
                                1102: 5
                            };
                            glob.code = obj[res.code];
                        }
                    }
                }
            });
            return info;
        },
        // 登录
        login: function (info) {
            info = (info && info.target ? info.data : info) || {};

            if(info.isCustom && glob.loginMethod) {
                return glob.loginMethod();
            }

            var globCode = _glob.code;
            if(glob.v && (glob.v === '2.5' && _glob.code === 2)
                || (glob.v === '2.1' && _glob.code === 4)) {
                globCode = 10000;
            }

            if(globCode === 10000) {
                if (!_glob.isLogin) {
                    delete _glob.params.infoData;
                    var urlData = '';
                    if(Object.keys(_glob.params).length !== 0) {
                        urlData = utils.setUrlParams(_glob.params);
                    }
                    var plat = info.plat || glob.platform,
                        url = glob.originOnly + '/' + plat + glob.pathCore + '?callback='
                            + encodeURI(origin + location.pathname
                                + urlData);

                    if (info.isUrl) return url;
                    // 登陆前，清除登录标识
                    utils.cookie.del('CASGTC', '.changyou.com');
                    // 清除原弹窗
                    dialog.hideMask();
                    switch (plat) {
                        case 'warframe':
                        case 'changyouwg':  // 星际战甲、海战世界
                            utils.win.open(496, 360, url);
                            break;
                        case 'changyou':     // 畅游平台
                            if (isMobile) {
                                if (glob.isForceMobileLogin || info.m === 1) {
                                    var width = document.documentElement.clientWidth;
                                    if(width >=1000) {
                                        utils.win.open(1000, 1600, url);
                                    }else if (width >= 800) {
                                        utils.win.open(800, 1200, url);
                                    } else if(width >= 600) {
                                        utils.win.open(570, 1000, url);
                                    } else {
                                        utils.win.open(320, 550, url);
                                    }
                                    if(isMobile && isIos) {
                                        // 监听键盘打开收起，修复IOS12系统引起的点击错位
                                        window.onmessage = utils.debounce(function(event) {
                                            event.data.isReset && utils.backTop();
                                        }, 300, false);
                                    }
                                } else
                                    window.location.href = url
                            } else {
                                if (glob.isForceMobileLogin || info.pc === 1)
                                    utils.win.open(320, 550, url);
                                else
                                    utils.win.open(496, 360, url);
                            }
                            break;
                        case 'cyou3':       // 橙柚
                            url += '&' + $.param({
                                from: info.from,
                                type: info.type
                            });
                            isMobile ? window.location.href = url : utils.win.open(490, 470, url);
                            break;
                        case 'wechat':      // 微信
                            if(isWechat) {
                                var timestampNow = Date.now(),
                                    timestampBefore = storage.getIsWxLogin();
                                if(!storage.getIsWxLogin() || (timestampNow - timestampBefore > 30 * 60 * 1000)) {
                                    storage.setIsWxLogin();
                                    window.location.href = url;
                                }
                            }
                            break;
                        case 'dj':
                            try {
                                djLogin();
                            }catch (e) {
                                message.warning('请先引入刀剑登录弹窗碎片及样式,可参照活动:/dj/goddess/20200509/pc/index.shtml;或者使用方法 ja.dlogin')
                            }
                            break;
                        default:
                            alert('暂时还没有该平台登陆功能');
                    }
                }
            }else {
                glob.isAlert && opt.msg[globCode] && alert(opt.msg[globCode]);
            }
        },
        loginUrl: function() {
            return this.login({ isUrl: true })
        },
        // 退出/注销
        logout: function () {
            // 微信退出
            function logoutAct() {
                $.ajax({
                    type: 'POST',
                    url: glob.originAll + glob.pathCore + '/logout',
                    success: function (res) {
                        if (['changyou', 'warframe', 'wechat', 'changyouwg'].indexOf(glob.platform) !== -1) {
                            utils.cookie.del('CASGTC', '.changyou.com');
                            // location.href = 'https://auth.changyou.com/logout.jsp?b=' + location.href.split("#")[0] + '&co=' + utils.cookie.get("CASGTC");
                        }
                        utils.reload();
                    }
                });
            }

            if (isWechat && (glob.isWxLogin || glob.platform === 'wechat')) {   // 微信平台退出
                $.ajax({
                    type: 'POST',
                    url: glob.originOnly + '/wechat/auto/cancel',
                    headers: {'PLAT': 'wechat'},
                    success: function (res) {
                        if (res.code === 10000) {
                            storage.removeIsWxLogin();
                            logoutAct();
                        } else if (res.code == 1012) {    // 页面停留时间过长，登录状态失效
                            utils.reload();
                        } else {
                            alert(res.message)
                        }
                    }
                });
            } else {
                logoutAct();
            }
        },
        // 获取用户信息
        getUserInfo: function (plat) {
            plat = plat || glob.platform;
            var resInfo = undefined;
            $.ajax({
                url: glob.originOnly + '/' + plat + '/user/info',
                async: false,
                headers: {'PLAT': plat},
                success: function (res) {
                    if (res.code === 10000) {
                        resInfo = res.data;
                        if (plat !== 'wechat' || glob.platform === 'wechat') {
                            _glob.isLogin = true;
                        }
                        if (plat === 'wechat') {
                            _glob.wechatInfo = resInfo;
                        } else {
                            _glob.userInfo = resInfo;
                        }
                    } else {
                        if (plat === 'wechat') {
                            user.login({plat: 'wechat'});
                            resInfo = false;
                        } else
                            _glob.isLogin = false;
                    }
                }
            });
            return resInfo;
        },
        // 获取验证码
        getCode: function (phone) {        // variate 类型 string、number、object、function，通过类型判断
            var info,
                codeInit = 60,
                styleSheet = glob.style,
                $btnPhoneCode = $(glob.ele.btnPhoneCode),
                styleBefore = styleSheet.beforeCode,     // 默认样式，可点击
                styleAfter = styleSheet.afterCode,   // 请求过程中、或倒计时中，不可点击
                errMsg = verify.phone(phone),
                btnValue = $btnPhoneCode.text();    // 获取 发送验证码按钮 原内容

            if (errMsg) return alert(errMsg);

            $btnPhoneCode.html('发送中...').css(styleAfter);

            $.ajax({
                type: 'POST',
                url: glob.originOnly + '/phone/core/zhpt/sendcode',
                async: false,
                data: {phone: phone},
                success: function (res) {
                    info = res;
                    if (res.code === 10000) {
                        $btnPhoneCode.css(styleAfter);
                        var codeNum = codeInit,
                            timer = setInterval(function () {
                                $btnPhoneCode.text(codeNum + 's');
                                if (codeNum <= 0) {
                                    $btnPhoneCode.text(btnValue).css(styleBefore);
                                    clearInterval(timer);
                                }
                                codeNum--;
                            }, 1000)
                    } else {
                        $btnPhoneCode.text(btnValue).css(styleBefore);
                        alert(res.message);
                    }
                }
            });

            return info;
        },
        // 手机号与验证码登陆
        loginPhone: function (phone, code) {
            var info,
                styleSheet = glob.style,
                $btnPhone = $(glob.ele.btnPhone),
                btnValue = $btnPhone.text(),
                styleBefore = styleSheet.beforePhone,     // 默认样式，可点击
                styleAfter = styleSheet.afterPhone,   // 请求过程中、或倒计时中，不可点击
                errorPhone = verify.phone(phone),
                errorPhoneCode = verify.phoneCode(code);

            if (errorPhone) return alert(errorPhone);

            if (errorPhoneCode) return alert(errorPhoneCode);

            $btnPhone.text('登录中...').css(styleAfter);

            $.ajax({
                type: 'POST',
                url: glob.originOnly + '/phone' + glob.pathCore + '/phonelogin',
                async: false,
                data: {phone: phone, code: code},
                headers: {'PLAT': 'phone'},
                success: function (res) {
                    info = res;
                    if (res.code === 10000) {
                        // $btnPhone.text(btnValue).css(styleBefore);
                    } else {
                        $btnPhone.text(btnValue).css(styleBefore);
                        alert(res.message);
                    }
                }
            });

            return info;
        },
        // 查询当前微信是否绑定账号
        wxStatus: function () {
            var info = {};
            if(isWechat) {
                if(!glob.isWxLogin) message.error('请先设置 isWxLogin 为 true');
                if(_glob.wechatInfo) {
                    $.ajax({
                        type: 'POST',
                        url: glob.originOnly + '/wechat/auto/isbind',
                        async: false,
                        headers: {'PLAT': 'wechat'},
                        success: function (res) {
                            info = res;
                        }
                    });
                }
            }
            return info;
        },
        // 微信绑定用户，自动登录
        wxAutoLogin: function (code) {
            if (code === 1) {
                location.href = urlWxBind;
                return false;
            }
            if(isWechat) {
                $.ajax({
                    type: 'POST',
                    url: glob.originOnly + '/wechat/auto/autologin',
                    headers: {'PLAT': 'wechat'},
                    async: true,
                    success: function (res) {
                        if (res.code === 10000) {
                            utils.reload();
                        } else if (res.code == 1012) {
                            storage.setMethod('wxAutoLogin');
                            user.login({plat: 'wechat'});
                        } else {
                            alert(res.message);
                        }
                    }
                });
            }
        },
        // 获取微信初始化参数
        wxConfig: function() {
            var info;
            if(!glob.appId) return message.error('微信初始化需要appId，请联系后台开发添加');
            $.ajax({
                url: origin + '/wechat/web/' + glob.appId + '/config',
                async: false,
                success: function (data) {
                    if (data.config) {
                        info = data.config;
                    } else {
                        message.error('微信初始化失败，config接口异常，' + data.msg);
                    }
                }
            });
            return info;
        }
    };
    var user = new User();

    /**
     * == 微信通用模块 ==
     **/
    function Wechat() {
    }
    Wechat.prototype = {
        wxInit: function(fun) {
            $.getScript('https://res.wx.qq.com/open/js/jweixin-1.4.0.js', function() {
                if(!glob.wxConfigInfo) glob.wxConfigInfo = user.wxConfig() || {};
                var configInfo = glob.wxConfigInfo;
                wx.config({
                    debug: glob.isWxDebug,     // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。
                    appId: configInfo.appId,           // 必填，公众号的唯一标识
                    timestamp: configInfo.timestamp,   // 必填，生成签名的时间戳
                    nonceStr: configInfo.nonceStr,     // 必填，生成签名的随机串
                    signature: configInfo.signature,   // 必填，签名，见附录1
                    jsApiList: [                        // 必填，需要使用的JS接口列表，所有JS接口列表见附录2
                        'translateVoice',           // 识别音频并返回识别结果接口
                        'onMenuShareTimeline',      // 分享到朋友圈
                        'onMenuShareAppMessage',    // 分享给朋友
                        'onMenuShareQQ',            // 分享到QQ
                        'onMenuShareQZone',         // 分享到QQ空间
                        'onMenuShareWeibo',         // 分享到腾讯微博
                        'hideMenuItems',            // 批量隐藏功能按钮接口
                        'showMenuItems',            // 批量显示功能按钮接口
                        'hideAllNonBaseMenuItem'    // 隐藏所有非基础按钮接口
                    ]
                });
                fun && fun();
            })
        },
        // 分享
        share: function (options) {
            if (isWechat) {
                var _options = {
                    type: 'link',
                    shareList: [
                        'onMenuShareTimeline',      // 分享到朋友圈
                        'onMenuShareAppMessage',    // 分享给朋友
                        'onMenuShareQQ',            // 分享到QQ
                        'onMenuShareWeibo',         // 分享到腾讯微博
                        'onMenuShareQZone'          // 分型到QQ空间
                    ]
                };
                $.extend(_options, options);
                var list = _options.shareList,
                    hideList = _options.hideMenuList,       // 除去不分享渠道，如朋友圈('onMenuShareTimeline')
                    showList = _options.showMenuList;       // 显示要显示的

                delete _options['shareList'];
                delete _options['hideMenuList'];
                delete _options['showMenuList'];

                this.wxInit(function() {
                    wx.ready(function () {
                        for (var i in list) {
                            var shareType = list[i];
                            if (typeof wx[shareType] === 'function') {
                                wx[shareType](_options);
                            }
                        }
                        hideList && wx.hideMenuItems({ menuList: hideList });
                        showList && wx.showMenuItems({ menuList: showList });
                    })
                })
            }
        }
    };
    var wechat = new Wechat();

    /**
     * == 活动通用模块 ==
     **/
    function Activity() {
    }
    Activity.prototype = {
        // 龙门标识添加
        longmen: function (obj) {
            var imgN = 'longmen_test.png',
                $parent = $('body');
            obj = obj || {};
            if (obj.color === 'white' || obj.color === '#fff' || obj.color === '#fffff') {
                imgN = 'longmen_test_white.png'
            }
            if(obj.parent) {
                if(typeof obj.parent === 'string' || typeof obj.parent.length === 'undefined') {
                    $parent = $(obj.parent);
                }else if(typeof obj.parent === 'object') {
                    $parent = obj.parent;
                }
            }

            $('<img />').attr('src', imgHost + '/xtl/logo/' + imgN).css($.extend({
                width: 80,
                position: 'absolute',
                top: 20,
                left: 20,
                zIndex: 10
            }, obj)).appendTo($parent);
        },
        // 百度事件统计，原始
        baiduFormer: function (type, action, tag) {
            if (window._hmt) {
                window._hmt.push(['_trackEvent', type, action, tag]);
            } else {
                message.error('请先添加百度统计代码');
            }
        },
        // 百度事件统计，通用
        baiduEvent: function (actName, sign, action, isPcM, isTwo) {
            if (window._hmt) {
                var cid = glob.cyscid
                    , tid = glob.cystid
                    , remark = isTwo ? ((cid ? ('cid=' + cid) : '无cid') + '/' + (tid ? ('tid=' + tid) : '无tid')) : (cid || '无');
                if (isPcM) remark += ('/' + (isMobile ? 'm' : 'pc'));
                window._hmt.push(['_trackEvent', actName + sign, action + sign, remark + '/' + sign]);
            } else {
                message.error('请先添加百度统计代码');
            }
        },
        // 二选一登录弹窗（天龙）
        tlogin: function (info) {
            info = (info && info.target ? info.data : info) || {};
            if (isMobile && isWechat) {
                if (!glob.isWxStatus && !_glob.wxBindName) {
                    _glob.wxBindName = user.wxStatus().data;
                }
                var isBind = !!_glob.wxBindName;
                var imgBase = imgHost + '/xtl/main/20200513/';
                if ($('.login_or_wrapper').length === 0) {
                    var css = {
                        bg: 'background: url(' + imgBase + 'login_or_bg.png) no-repeat center center;' +
                            'width: 320px;height: 280px;' +
                            'background-size: 100% auto; position: relation;',
                        title: 'text-align: center;margin: 0;margin-top: 36px;' +
                            'font-size: 20px; height: 26px; font-weight: normal;',
                        subTitle: 'color: #a64e39; font-size: 16px; margin: 16px 0; height: 21px;',
                        box: 'display: flex;justify-content: center; ' +
                            'text-align: center;width: 93%;margin: 0 auto;',
                        wrap: 'width: 50%;',
                        imgWrap: 'display: block;width: 70px;height: 70px;' +
                            'margin: 28px auto 10px;',
                        wx: 'background: url(' + imgBase + 'wechat.png) no-repeat center center;',
                        wxbtn: 'width: 100px; color: #fff; font-size: 12px;' +
                            'background: #DF6738;' +
                            'text-decoration: none; padding: 5px 0; margin: 20px auto 0;' +
                            'border-radius: 5px; display:' + (isBind ? "none" : "block") + ';',
                        wxAccount: 'color: gray; font-size: 12px; text-decoration:none;' +
                            'display:' + (isBind ? "block" : "none") + ';',
                        cy: 'background: url(' + imgBase + 'changyou.png) no-repeat center center;',
                        cyBtn: 'font-size: 12px; color: #565344; line-height: 12px;' +
                            'text-decoration: none; padding: 0 5px;',
                        close: 'width: 30px; height: 30px; position: absolute; top: 0px; right: -10px;' +
                            'background: url(' + imgBase + 'close.png) no-repeat center center;' +
                            'background-size: 100% 100%;',
                    };
                    var html = '<div class="login_or_wrapper ja_login_box" style="' + css.bg + '">' +
                        '<h3 style="' + css.title + '">请选择登录方式</h3>' +
                        '<div style="' + css.box + '">' +
                        '<div style="' + css.wrap + '">' +
                        '<p style="' + css.subTitle + '">已绑定微信入口</p>' +
                        '<a href="javascript:;" onclick="ja.wxAutoLogin(' + (!isBind && 1) + ')" style="' + css.imgWrap + css.wx + '"></a>' +
                        '<a href="' + urlWxBind + '" style="' + css.wxbtn + '">点击前往绑定</a>' +
                        '<a href="javascript:;" style="' + css.wxAccount + '">' + _glob.wxBindName + '<br/>已绑定</a>' +
                        '</div>' +
                        '<div style="' + css.wrap + '">' +
                        '<p style="' + css.subTitle + '">未绑定微信入口</p>' +
                        '<a href="javascript:;" onclick="ja.login(' + JSON.stringify(info).replace(/"/g, '&quot;') + ')" style="' + css.imgWrap + css.cy + '"></a>' +
                        '<a href="javascript:;" style="' + css.cyBtn + '">未在微信绑定过畅游帐号的玩家可在此登录</a>' +
                        '</div>' +
                        '</div>' +
                        '<div class="login_or_close" onclick="ja.hideMask($(this).parent())" style="' + css.close + '"></div>' +
                        '</div>';
                    $('body').append(html);
                }
                dialog.popup($('.login_or_wrapper'));
            } else {
                user.login(info);
            }
        },
        // 手机号登录
        plogin: function () {
            function htmlCreate() {
                var html = '<div class="login_phone_wrapper ja_login_box">' +
                    '<h3 class="plogin_title">手机号登录</h3>' +
                    '<ul class="plogin_list">' +
                    '<li><input type="text" maxlength="11" class="plogin_phone" placeholder="输入手机号"/></li>' +
                    '<li>' +
                    '<input type="text" maxlength="6" class="plogin_phone_code" placeholder="验证码"/>' +
                    '<a href="javascript:;" class=" btn plogin_btn_phone_code">获取验证码</a>' +
                    '</li>' +
                    '<li><a href="javascript:;" class=" btn plogin_btn_phone">登 录</a></li>' +
                    '</ul>' +
                    '<a href="javascript:;" class="plogin_close" onclick="ja.hideMask($(this).parent())"></a>' +
                    '</div>';
                $('body').append(html);
            }
            function cssCreate() {
                $('.login_phone_wrapper').css({
                    width: 320, height: 240,
                    position: 'relation',
                    background: '#fff',
                    borderRadius: '8px'
                });
                $('.login_phone_wrapper *').css({ boxSizing: 'border-box' });
                $('.login_phone_wrapper .btn').css({
                    background: '#F8F8F8',
                    textDecoration: 'none',
                    padding: '2px 10px',
                    borderRadius: 5,
                    border: '1px solid #ccc',
                    display: 'inline-block',
                    height: 38,
                    lineHeight: '32px',
                    color: '#000'
                });
                $('.plogin_list').css({ paddingLeft: 10 });
                $('.plogin_list>li').css({ margin: '0 0 10px 10px',  overflow: 'hidden' });
                $('.plogin_title').css({
                    textAlign: 'center',
                    margin: '20px 0 20px 0',
                    fontSize: 24,
                    fontWeight: 'normal'
                });
                $('.login_phone_wrapper input').css({
                    height: 40,
                    borderRadius: 5,
                    padding: '3px 10px',
                    outline: 'none',
                    border: '1px solid #ccc'
                });
                $('.plogin_phone').css({ width: 280, });
                $('.plogin_phone_code').css({ width: 150,  float: 'left' });
                $('.plogin_btn_phone_code').css({
                    float: 'left',
                    marginLeft: 20,
                    width: 108,
                    textAlign: 'center'
                });
                $('.plogin_btn_phone').css({
                    width: 140,
                    background: '#1AAD19',
                    textAlign: 'center',
                    fontSize: 20,
                    color: '#fff',
                    display: 'block',
                    margin: '10px auto 0'
                });
                $('.plogin_close').css({
                    width: 25,
                    height: 25,
                    position: 'absolute',
                    top: -10,
                    right: -10,
                    background: '#ccc url(http://i0.cy.com/www/pop/close.png) no-repeat center center',
                    backgroundSize: '90% 90%',
                    borderRadius: '50%'
                });
            }
            function eventCreate() {
                $('.plogin_btn_phone_code').click(function() {
                    var phone = $('.plogin_phone').val();
                    glob.ele.btnPhoneCode = '.plogin_btn_phone_code';
                    user.getCode(phone)
                });
                $('.plogin_btn_phone').click(function() {
                    var phone = $('.plogin_phone').val();
                    var code = $('.plogin_phone_code').val();
                    glob.ele.btnPhone = '.plogin_btn_phone';
                    glob.style.beforePhone.background = '#1AAD19';
                    var phoneInfo = user.loginPhone(phone, code);
                    if(phoneInfo.code === 10000) {
                        dialog.hideMask();
                    }
                })
            }

            if ($('.login_phone_wrapper').length === 0) {
                htmlCreate();
                cssCreate();
                eventCreate();
            }
            dialog.popup($('.login_phone_wrapper'));
        },
        // 刀剑登录
        dlogin: function() {
            function htmlCreate() {
                var html = '<div class="login_dj_wrapper ja_login_box">' +
                    '<h3 class="dlogin_title">登录账号</h3>' +
                    '<ul class="dlogin_list">' +
                    '<li>账号:<input type="text" class="dlogin_accout"/>' +
                    '<a href="http://bo.account.changyou.com/reg/contract.jsp?game=DJ" ' +
                    'target="_blank" class=" btn dlogin_btn_phone_code">注册账号</a>' +
                    '</li>' +
                    '<li>密码:<input type="password" class="dlogin_password"/>' +
                    '<a href="http://bo.account.changyou.com/pwd/changepwd.jsp" ' +
                    'target="_blank" class=" btn dlogin_btn_phone_code">忘记密码</a>' +
                    '</li>' +
                    '<li>验证码:<input type="text" maxlength="6" class="dlogin_code"/>' +
                    '<img class="dlogin_code_img dlogin_btn_chang" src="/wx/wxmsg/activitys/image/generate" alt="验证码">' +
                    '<a href="javascript:;" class=" btn dlogin_btn_chang">换一个</a>' +
                    '</li>' +
                    '<li class="dloing_error"></li>' +
                    '<li><a href="javascript:;" class=" btn dlogin_btn_login">登录</a></li>' +
                    '</ul>' +
                    '<a href="javascript:;" class="dlogin_close" ' +
                    'onclick="ja.hideMask($(this).parent())">✕</a>' +
                    '</div>';
                $('body').append(html);
            }
            function cssCreate() {
                $('.login_dj_wrapper').css({
                    width: 370, height: 290,
                    position: 'relation',
                    background: '#fff',
                    borderRadius: '2px',
                    fontSize: '14px'
                });
                $('.login_dj_wrapper *').css({ boxSizing: 'border-box' });
                $('.login_dj_wrapper a').css({
                    textDecoration: 'none',
                    color: '#0072C6',
                    padding: '2px 10px',
                    height: 38,
                    lineHeight: '32px',
                    fontSize: '12px'
                });
                $('.dlogin_list').css({ paddingLeft: 25 });
                $('.dlogin_list>li').css({ margin: '0 0 10px 10px',  overflow: 'hidden' });
                $('.dlogin_title').css({
                    textAlign: 'center',
                    margin: '20px 0 20px 0',
                    fontSize: 24,
                    fontWeight: 'normal'
                });
                $('.login_dj_wrapper input').css({
                    height: 30,
                    borderRadius: 2,
                    padding: '3px 10px',
                    outline: 'none',
                    border: '1px solid #ccc',
                    margin: '0 2px 0 10px'
                });
                $('.dlogin_code').css({ width: 90,  margin: '0 0 0 5px' });
                $('.dlogin_code_img').css({ vertivalAlign: 'middle',  marginBottom: -5 });
                $('.dlogin_btn_login').css({
                    width: 140,
                    background: '#1AAD19',
                    textAlign: 'center',
                    fontSize: 20,
                    color: '#fff',
                    display: 'block',
                    margin: '10px auto 0'
                });
                $('.dloing_error').css({
                    color: '#ff6466',
                    fontSize: 12,
                    height: 16,
                    textAlign: 'center'
                });
                $('.dlogin_close').css({
                    width: 25,
                    height: 25,
                    padding: 0,
                    color: 'gray',
                    fontSize: 20,
                    fontWeight: 'bold',
                    position: 'absolute',
                    top: 3,
                    right: 10,
                    backgroundSize: '90% 90%',
                    borderRadius: '50%'
                });
            }
            function eventCreate() {
                // 换一个验证码
                $('.dlogin_btn_chang').click(function () {
                    var value = parseInt(Math.random()*10000);
                    $('.dlogin_code_img')
                        .attr('src', "/wx/wxmsg/activitys/image/generate?random_mark="+value)
                });
                // 登录
                $('.dlogin_btn_login').click(function() {
                    var account = $('.dlogin_accout').val(),
                        password = $('.dlogin_password').val(),
                        code = $('.dlogin_code').val(),
                        $error = $('.dloing_error');
                    if(!account) return $error.html('请输入账号');
                    if(!password) return $error.html('请输入密码');
                    if(!code) return $error.html('请输入验证码');
                    $error.html('');
                    $.ajax({
                        type:"post",
                        url: glob.originAll + glob.pathCore + "/djlogin?callback=" + encodeURI(location.href),
                        data:{
                            'cn': account,
                            'password': password,
                            'dj_nnex_code': code
                        },
                        success:function (outPut) {
                            switch (outPut.login) {
                                case '001': $error.text('请输入账号'); break;
                                case '002':
                                case '003':
                                case '009': $error.text('账号错误，请重新输入'); break;
                                case '004': $error.text('您的账号异常，请尝试更换账号登陆'); break;
                                case '005': $error.text('账号或密码错误'); break;
                                case '006': $error.text('请输入密码'); break;
                                case '007': $error.text('请输入验证码'); break;
                                case '008': $error.text('验证码错误，请重新输入'); break;
                                case '099': $error.text('账号验证系统繁忙，请稍后再试'); break;
                                case '010': $error.text('活动已结束或未开始'); break;
                                case '000':
                                    $('.dlogin_accout').val('');
                                    $error.html('');
                                    dialog.hideMask($('.ja_login_box'));
                                    window.location.href = outPut.redirect;
                                    break;
                                default:
                                    $error.text('系统繁忙，请稍后再试')
                            }
                        }
                    });
                })
            }

            if ($('.login_dj_wrapper').length === 0) {
                htmlCreate();
                cssCreate();
                eventCreate();
            }
            dialog.popup($('.login_dj_wrapper'));
        }
    };
    var activity = new Activity();

    /**
     * == 旧版本方法 ==
     **/
    function OldVersion() {
    }
    OldVersion.prototype = {
        utils: {
            urlAddSearch: function(url) {
                var paramsObj = storage.getParams();
                url += paramsObj ? ('?' + paramsObj) : '';
                return !isIos && isWechat ? utils.urlAddKey(url) : url;
            },
            url_add_key: utils.urlAddKey,
            objType: function(val) {
                var json = {
                    '[object Object]': 'object',
                    '[object Array]': 'array',
                    '[object Number]': 'number',
                    '[object Function]': 'function',
                    '[object Null]': 'null',
                    '[object Undefined]': 'undefined',
                    '[object Boolean]': 'boolean',
                    "[object String]" : 'string'
                };
                return json[Object.prototype.toString.call(val)]
            },
            longmen: activity.longmen
        },
        client: {
            ajax: function (type, url, variate, fun, plat) {
                switch (typeof variate) {
                    case 'object':
                        if(variate.header) {
                            var header = variate.header;
                            delete variate.header;
                        }
                        if(variate.contentType) {
                            var contentType = variate.contentType;
                            delete variate.contentType;
                        }
                        var params = variate;
                        break;
                    case 'function': fun = variate; break;
                    case 'string': plat = variate; break;
                    default: message.error('client.ajax使用错误');
                }
                $.ajax({
                    type: type,
                    url: url,
                    data: params || {},
                    dataType: 'json',
                    cache: false,
                    xhrFields: { withCredentials: true },
                    contentType: contentType,
                    headers: header,
                    success: function(res) {
                        fun(res)
                    }
                })
            },
            common: function(type, url, variate, fun, plat) {
                var opt = glob;
                switch (typeof variate) {
                    case 'string': plat = variate; break;
                    case 'object': var data = variate; break;
                    case 'function': fun = variate; break;
                }
                var baseUrl = opt.host + '/' + (plat || opt.platform);
                this.ajax(opt.isDebug ? 'GET': type, baseUrl + url, data || {}, fun, plat);
            },
            get: function(url, variate, fun, plat) {
                this.common('GET',  url, variate, fun, plat);
            },
            post: function(url, variate, fun, plat) {
                this.common('POST', url, variate, fun, plat);
            }
        },
        common: {
            // 常用表单长度限制，class名要对应
            input: function() {
                $(that.options.ele.inputPhone).keyup(function() {
                    $(this).siblings('.error').text('');
                    if($(this).val().length > 11) $(this).val($(this).val().slice(0, 11))
                });        // 手机号
                $(that.options.ele.inputPhoneCode).keyup(function() {
                    $(this).siblings('.error').text('');
                    if($(this).val().length > 6) $(this).val($(this).val().slice(0, 6))
                });     // 手机验证码
            },
            // 移动端初始化
            mobile: function() {
                $('input').blur(function() { window.scrollTo(0, 0) });  // 解决 H5 在输入弹框后页面留白问题
            },
            // 输出最新全局对象 glob
            glob: function() {
                return that.glob;
            },
            // 百度事件统计
            baiduEvent: function(actName, sign, action, isPcM, isTwo) {
                // isPcM, isTwo 非必填，一般不用
                if(window._hmt) {
                    var cid = that.glob.cyscid
                        , tid = that.glob.cystid
                        , remark = isTwo ? ((cid ? ('cid=' + cid) : '无cid') + '/' + (tid ? ('tid=' + tid) : '无tid')) : (that.glob.cyscid || '无');
                    if(isPcM) remark += ('/' + (that.glob.isMobile ? 'm' : 'pc'));
                    window._hmt.push(['_trackEvent', actName + sign, action + sign, remark + '/' +sign]);
                }else {
                    that.admin.error('请先添加百度统计代码');
                }
            }
        },
        http: {
            ajax: function (options) {
                $.ajax(options)
            },
            get: function(url, variate, fun) {
                var data = {};
                if(typeof variate === 'function') {
                    fun = variate;
                }else {
                    data = variate;
                }
                $.ajax({
                    type: 'GET',
                    url: glob.host + url,
                    data: data,
                    success: fun
                });
            },
            post: function(url, variate, fun, plat) {
                var data = {};
                if(typeof variate === 'function') {
                    fun = variate;
                }else {
                    data = variate;
                }
                $.ajax({
                    type: 'POST',
                    url: glob.host + url,
                    data: data,
                    success: fun
                });
            }
        },
        wx: {
            init: wechat.wxInit
        },
        user: {
            // 是否绑定微信
            wxIsBind: function(fun) {
                if(_glob.wechatInfo) {
                    $.ajax({
                        type: 'POST',
                        url: glob.originOnly + '/wechat/auto/isbind',
                        async: false,
                        headers: {'PLAT': 'wechat'},
                        success: function (res) {
                            fun && fun(res);
                        }
                    });
                }
            },
            loginAlert: function(plat) {
                user.login({ plat: plat });
            }
        }
    };

    /**
     * == 活动开发，最终构造函数 ==
     **/
    var JoinActivity = function () {
        this.options = {
            app: undefined,             // 应用 初始化必传项
            activity: undefined,        // 活动 初始化必传项
            version: undefined,         // 版本 初始化必传项
            platform: undefined,        // 平台 初始化必传项
            v: undefined,               // 当前要兼容的版本
            type: 0,                    // 版本固定后，通过 type 值区分之前之后项目
            isUserInfo: true,           // 是否获取用户信息
            isWxOnly: false,            // 是否只是在微信中访问
            isWxLogin: false,           // 是否微信授权
            isWxInit: false,            // 是否微信初始化
            isWxDebug: false,           // 是否开启微信debug调试
            isWxStatus: false,          // 是否查询微信绑定账号
            isDebug: false,             // 是否开启调试模式（只在debugDomain数组下域名生效）
            isVconsole: false,          // 是否启用vconsole（只在vconsoleDomain数组下域名生效）
            debugPath: '/config/json',  // debug 请求基础路径
            isAlert: true,              // 是否弹出活动异常弹窗
            isAlertLogin: true,         // 是否弹出登录异常弹窗
            loginMethod: null,       // 登录方法名，默认
            host: $.inArray(location.host, arrHost) !== -1 ? location.protocol + '//join-activity.changyou.com' : origin,      // 接口请求域名，默认同域名
            wxShare: undefined,         // 微信分享内容
            msg: {
                1106: '活动未开始',
                1103: '活动已结束',
                1102: '活动无效'
            },
            ele: {
                inputPhone: '.input_phone',
                inputPhoneCode: '.input_phone_code',
                btnPhone: '.btn_phone',
                btnPhoneCode: '.btn_phone_code',
                btnWxBind: '.btn_wx_bind'
            },
            style: {
                beforeCode: {background: '', 'pointer-events': 'auto'},
                afterCode: {background: '#9c9c9c', 'pointer-events': 'none'},
                beforePhone: {background: '', 'pointer-events': 'auto'},
                afterPhone: {background: '#9c9c9c', 'pointer-events': 'none'},
            },
            ready: function () { },   // 回调函数
        };
        this.glob = _glob;
        that = this;
    };
    JoinActivity.fn = JoinActivity.prototype = {
        config: function (options) {
            var opt = utils.deepMerge(this.options, options),           // 合并配参
                arrMust = ['app', 'activity', 'version', 'platform'],   // 初始化必填项，没有配置，给以提示
                show = new MidWare(),
                _this = this;

            // 传参数据重置
            show.use(function(about, next) {
                var urlParams = utils.getUrlParams();
                if(Object.keys(urlParams).length !== 0) {
                    delete urlParams.CYSCID
                    delete urlParams.CYSTID
                    location.href = origin + location.pathname + '?' + $.param(urlParams)
                }else {
                    next();
                }
            });

            // 配置异常判断
            // （1、必填项没填；2、platform = wechat，但不是在微信环境下；3、isWxOnly = true）
            show.use(function (about, next) {
                message.console(name + '-version', version);  // 输出ja版本号
                if (!isWechat && (opt.platform === 'wechat' || opt.isWxOnly)) {
                    return _this.output('请在微信中访问');
                }
                for (var i = 0; i < arrMust.length; i++) {
                    var item = arrMust[i];
                    if (!opt[item]) {
                        return _this.output(item + '为必填项');
                    } else
                        message.console(item, opt[item]);
                }
                next();
            });

            // vconsole、isDebug 开启判断
            show.use(function (about, next) {
                if (opt.isVconsole && $.inArray(location.host, vconsoleDomain) !== -1) {
                    utils.vconsole();
                }
                if (opt.isDebug && $.inArray(location.host, debugDomain) === -1) {
                    opt.isDebug = false
                }
                next();
            });

            // 配置无异常后，进行全局数据整理
            show.use(function (about, next) {
                glob.appName = [opt.app, opt.activity, opt.version, opt.platform].join('-');      // 当前活动唯一标识

                var urlCenter = opt.isDebug ? opt.debugPath : '',
                    storageParams = storage.getParams(),
                    params = utils.getParams();

                if(storageParams) params = $.extend(storageParams, params);

                storage.setParams(params);

                var urlArr = location.pathname.split('/')
                var nameArr = urlArr[urlArr.length - 1].split('.')[0].split('-');

                $.extend(glob, opt, {
                    pathCore: '/core/login/' + opt.app + '/' + opt.activity + '/' + opt.version,  // 通用接口中间段
                    originOnly: opt.host + urlCenter,
                    originAll: opt.host + urlCenter + '/' + opt.platform,
                    cyscid: nameArr[0],
                    cystid: nameArr[1]
                });

                $.extend(_glob, {
                    app: opt.app,
                    activity: opt.activity,
                    version: opt.version,
                    platform: opt.platform,
                    params: params || {},
                    host: opt.host,
                    originOnly: glob.originOnly,
                    originAll: glob.originAll
                });

                next();
            });

            // 低版本处理
            show.use(function(about, next) {
                var module = 'client';
                if(opt.v === '2.5') {
                    if(opt.type === 1) {
                        module = 'http';
                    }
                    MixinSimple(JoinActivity, OldVersion, module, 'get', 'post', 'ajax');
                }
                next();
            });

            // 活动信息接口请求，拿到token、activityInfo、appId
            show.use(function (about, next) {
                setupAjax();
                var infoInit = user.getToken() || {};
                var item = infoInit.data;
                $.extend(_glob, {
                    code: infoInit.code,
                    message: infoInit.message,
                    activityInfo: item && item.activity
                });
                $.extend(glob, {
                    token: item && item.token,
                    appId: item && item.activity.wxId,
                    isForceMobileLogin: item && item.client && item.client.isForceMobileLogin
                });
                if (infoInit.code === 10000) {
                    setupAjax();
                    next();
                } else {
                    var msg = glob.msg[_glob.code];
                    _this.output(msg);
                }
            });

            // 判断获取微信用户信息，如果得不到，会唤起微信用户授权
            show.use(function (about, next) {
                if (isWechat && (opt.platform === 'wechat' || opt.isWxLogin)) {
                    user.getUserInfo('wechat');
                }
                next();
            });

            // 查看是否有待执行方法，唤起执行
            // （1、微信绑定账号自动登陆，调起 wxAutoLogin；2、接口返回“登录状态检测失败”调起 loginMethod）
            show.use(function (about, next) {
                _this.loginMethod = glob.loginMethod || user.login;
                var method = storage.getMethod();
                if (method) {
                    storage.removeMethod();
                    _this.loginMethod();
                }
                next();
            });

            // 查询微信是否绑定账号信息
            show.use(function (about, next) {
                if (isWechat && opt.isWxStatus) {
                    var wxStatusInfo = user.wxStatus();
                    if (wxStatusInfo.code === 10000) {
                        _glob.wxBindName = wxStatusInfo.data;
                    }
                    next();
                } else
                    next();
            });

            // 再获取账号用户账号信息，如果得不到，则为未登录状态
            show.use(function (about, next) {
                if (opt.isUserInfo) {
                    var userInfo = user.getUserInfo();
                    if(opt.v) _this.oldMag.code();
                    next();
                } else
                    next();
            });

            // 地址栏后台错误判断（1、如果账号没有登录，且url存在jcode值）
            show.use(function(about, next) {
                if(opt.isAlertLogin) {
                    var jcode = utils.getQueryString('jcode');
                    if(!_glob.isLogin && jcode) {
                        var errMsg = '';
                        switch (Number(jcode)) {
                            case 1001: errMsg = '登录异常'; break;
                            case 1007: errMsg = '网络繁忙'; break;
                            case 1300: errMsg = '畅游登录异常'; break;
                            case 3103: errMsg = '您的账号已封停'; break;
                            default: errMsg = '登录异常';
                        }
                        alert(errMsg);
                        utils.reload();
                    }
                }
                next();
            });

            // 判断微信是否初始化、和微信分享
            show.use(function (about, next) {
                if (isWechat && opt.isWxInit) {
                    wechat.wxInit(function() {
                        if(opt.wxShare) wechat.share(opt.wxShare);
                        next();
                    });
                } else
                    next();
            });

            // 最终输出，给到初始化结果
            show.use(function (about, next) {
                _this.output();
            });

            // 执行
            show.handleRequest();
        },
        output: function(msg) {
            if (typeof msg === 'string') alert(msg);

            glob.ready && glob.ready(_glob);

            Object.defineProperty(glob, 'ready', {
                set: function(fun) {
                    fun && fun(_glob);
                }
            });
        },
        ready: function (fun) {
            glob.ready = fun;
        },
        oldMag: {
            code: function() {
                switch (glob.v) {
                    case '2.4':
                    case '2.5':
                        _glob.code = _glob.isLogin ? 1 : 2;
                        break;
                    case '2.1':
                        _glob.code = _glob.isLogin ? 1 : 4;
                        break;
                }
            }
        },
        utils: utils,
        user: user,
        wx: wechat
    };

    /* == 工具类模块 == */
    Mixin(JoinActivity, Utils);
    Mixin(JoinActivity, Dialog);
    Mixin(JoinActivity, Message);
    Mixin(JoinActivity, Verify);

    /* == 业务类模块 == */
    Mixin(JoinActivity, Activity);
    Mixin(JoinActivity, User);
    Mixin(JoinActivity, Wechat);

    /* == 与旧版方法深层合并 == */
    MixinDeep(JoinActivity, OldVersion);

    window[name] = new JoinActivity();

}(window));
